package com.yami.shop.multishop.controller;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yami.shop.bean.model.*;
import com.yami.shop.bean.vo.BlockchainInfoVo;
import com.yami.shop.bean.vo.BlockchainShopVO;
import com.yami.shop.common.annotation.RedisLock;
import com.yami.shop.common.annotation.SysLog;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.security.multishop.util.SecurityUtils;
import com.yami.shop.service.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * 链平台管理
 *
 * @author lgh
 */
@RestController
@RequestMapping("/prod/blockchain")
@Tag(name = "链平台接口")
public class BlockchainController {

    @Autowired
    private BlockchainService blockchainService;
    @Autowired
    private BlockchainShopService blockchainShopService;
    @Autowired
    private ProductService productService;
    @Autowired
    private ShopDetailService shopDetailService;
    @Autowired
    private ShopChainApplyService shopChainApplyService;

    @GetMapping("/info/{blockchainId}")
    @Operation(summary = "根据链平台id获取链平台信息", description = "根据链平台id获取链平台信息")
    public ServerResponseEntity<Blockchain> info(@PathVariable("blockchainId") Long blockchainId) {
        // 获取数据库中的链平台，如果链平台为空则抛异常
        Blockchain blockchain = blockchainService.getBlockchainByBlockchainId(blockchainId);
        if (ObjectUtil.isNull(blockchain)) {
            throw new YamiShopBindException("yami.no.auth");
        }
        return ServerResponseEntity.success(blockchain);
    }

    @GetMapping("/list")
    @Operation(summary = "获取链平台列表（不分页）", description = "获取链平台列表（不分页）")
    public ServerResponseEntity<List<Blockchain>> list(@ParameterObject Blockchain blockchain) {
        List<Blockchain> brandList = blockchainService.listByParams(blockchain);
        return ServerResponseEntity.success(brandList);
    }

    @SysLog("保存链平台")
    @PostMapping
    @PreAuthorize("@pms.hasPermission('prod:blockchain:save')")
    @Operation(summary = "保存链平台信息", description = "保存链平台信息")
    @RedisLock(lockName = "saveBlockchainLock", key = "#Blockchain")
    public ServerResponseEntity<Long> save(@RequestBody Blockchain blockchain) {
        Integer count = blockchainService.getBlockchainName(blockchain);
        if (count > 0) {
            // 类目名称已存在！
            throw new YamiShopBindException("yami.blockchain.name.exist");
        }
        blockchain.setOrderNum(Objects.isNull(blockchain.getOrderNum()) ? 0 : blockchain.getOrderNum());
        blockchainService.saveBlockchain(blockchain);
        return ServerResponseEntity.success(blockchain.getId());
    }

    @SysLog("更新链平台")
    @PutMapping
    @Operation(summary = "更新链平台信息", description = "更新链平台信息")
    public ServerResponseEntity<String> update(@RequestBody Blockchain blockchain) {
        // 获取数据库中的链平台，如果链平台为空则抛异常
        blockchainService.getBlockchainByBlockchainId(blockchain.getId());
        Integer count = blockchainService.getBlockchainName(blockchain);
        if (count > 0) {
            // 类目名称已存在！
            throw new YamiShopBindException("yami.category.name.exist");
        }
        blockchainService.updateBlockchain(blockchain);
        return ServerResponseEntity.success();
    }

    @SysLog("删除链平台")
    @DeleteMapping("/{blockchainId}")
    @Operation(summary = "根据链平台id删除链平台", description = "根据链平台id删除链平台")
    public ServerResponseEntity<String> delete(@PathVariable("blockchainId") Long blockchainId) {
        Blockchain blockchain = blockchainService.getBlockchainByBlockchainId(blockchainId);
        long categoryProdCount = productService.count(new LambdaQueryWrapper<Product>().eq(Product::getChain, blockchain.getCode()).ne(Product::getStatus, -1));
        if (categoryProdCount > 0) {
            // 该链平台下还有商品，请先删除该链平台下的商品
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.category.delete.check"));
        }
        blockchainService.deleteBlockchain(blockchain);
        return ServerResponseEntity.success();
    }

    @GetMapping("/platformBlockchain")
    @Operation(summary = "获取平台所有上架的链平台", description = "获取平台所有上架的链平台")
    public ServerResponseEntity<List<Blockchain>> listBlockchain(@ParameterObject Blockchain blockchain) {
        List<Blockchain> list = blockchainService.listByParams(blockchain);
        return ServerResponseEntity.success(list);
    }

    @PostMapping("/signing")
    @Operation(summary = "批量签约链平台（申请店铺时使用）", description = "批量签约链平台（申请店铺时使用）")
    public ServerResponseEntity<Void> signingBlockchain(@RequestBody List<BlockchainShop> blockchainShopList) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        ShopDetail shopDetailByShopId = shopDetailService.getShopDetailByShopId(shopId);
        blockchainShopList.forEach(s->{
            s.setShopCode(shopDetailByShopId.getChannelCode());
            s.setShopId(shopId);
        });
        blockchainShopService.signingBlockchain(blockchainShopList, shopId, false);
        return ServerResponseEntity.success();
    }

    @GetMapping("/listSigningBlockchain")
    @Operation(summary = "获取签约的链平台列表（状态参数为空则返回所有）", description = "获取签约的链平台列表（状态参数为空则返回所有）")
    @Parameter(name = "status", description = "签约状态：1：已通过 0待审核 -1未通过")
    public ServerResponseEntity<List<BlockchainShopVO>> listByShopId(@RequestParam(name = "status", required = false) Integer status) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        List<BlockchainShopVO> blockchainShopVOList = blockchainShopService.listSigningBlockchainByShopId(shopId);
        if (Objects.nonNull(status)) {
            blockchainShopVOList = blockchainShopVOList.stream().filter(item -> Objects.equals(item.getBlockchainShopStatus(), status)).collect(Collectors.toList());
        }
        return ServerResponseEntity.success(blockchainShopVOList);
    }

    @GetMapping("/listAvailableSigningBlockchain")
    @Schema(description = "获取店铺签约的可用链平台列表(发布商品时使用）", name = "获取店铺签约的可用链平台列表(发布商品时使用）")
    public ServerResponseEntity<List<BlockchainShopVO>> listAvailableSigningBlockchain() {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        List<BlockchainShopVO> blockchains = blockchainShopService.listAvailableSigningBlockchain(shopId);
        return ServerResponseEntity.success(blockchains);
    }

    @GetMapping("/listByIsCoin")
    @Operation(summary = "获取商铺链未添加铸币权限列表", description = "获取商铺链未添加铸币权限列表")
    public ServerResponseEntity<List<BlockchainShopVO>> listByIsCoin(@RequestParam(name = "applyId", required = false) Long applyId) {
        List<BlockchainShopVO> brandList = blockchainShopService.listByIsCoin(SecurityUtils.getShopUser().getShopId(), applyId);
        return ServerResponseEntity.success(brandList);
    }

    @GetMapping("/signingByShopId")
    @Operation(summary = "根据店铺id分页获取签约的链平台列表", description = "根据店铺id分页获取签约的链平台列表")
    public ServerResponseEntity<List<BlockchainShopVO>> pageSigningByShopId() {
        List<BlockchainShopVO> brandShopPage = blockchainShopService.listSigningBlockchainAndLang(SecurityUtils.getShopUser().getShopId());
        return ServerResponseEntity.success(brandShopPage);
    }

    @PostMapping("/updateSynchronizationStatus")
    @Operation(summary =  "修改商品同步状态", description = "修改商品同步状态")
    public ServerResponseEntity<Void> updateSynchronizationStatus(Long blockchainShopId,Integer isSynchronization){
        blockchainShopService.updateSynchronizationStatus(blockchainShopId, isSynchronization);
        return ServerResponseEntity.success();
    }

    @GetMapping("/listbyshopId")
    @Operation(summary = "获取链平台列表（不分页）", description = "获取链平台列表（不分页）")
    public ServerResponseEntity<List<BlockchainInfoVo>> listbyshopId() {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        List<BlockchainInfoVo> blockchainInfoVos = blockchainService.listbyshopId(shopId);
        return ServerResponseEntity.success(blockchainInfoVos);
    }

    @GetMapping("/listSigningByShopId")
    @Operation(summary = "根据店铺id获取签约的链平台列表", description = "根据店铺id获取签约的链平台列表")
    @Parameters(value = {@Parameter(name = "status", description = "状态 1:启用, 0:禁用")})
    public ServerResponseEntity<List<BlockchainShopVO>> listSigningByShopId(@RequestParam(name = "status", required = false) Integer status) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        List<BlockchainShopVO> blockchainShopList = blockchainShopService.listSigningByShopId(shopId, status);
        return ServerResponseEntity.success(blockchainShopList);
    }

    @GetMapping("/deleteBlockchainShop")
    @Operation(summary = "删除商铺签约链", description = "删除商铺签约链")
    @Parameters(value = {@Parameter(name = "blockchainId", description = "链平台id")})
    public ServerResponseEntity<Void> deleteBlockchainShop(@RequestParam("blockchainId") Long blockchainId) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        BlockchainShop blockchainShop = blockchainShopService.getOne(new LambdaUpdateWrapper<BlockchainShop>().eq(BlockchainShop::getShopId, shopId).eq(BlockchainShop::getBlockchainId, blockchainId));
        if (blockchainShop.getStatus() == 1) {
            // 删除对应链的铸币能力申请记
            shopChainApplyService.update(new LambdaUpdateWrapper<ShopChainApply>().set(ShopChainApply::getStatus, 0).eq(ShopChainApply::getShopId, shopId).eq(ShopChainApply::getChainCode,blockchainShop.getBlockchainCode()));
        }
        blockchainShopService.delete(shopId, blockchainId);
        return ServerResponseEntity.success();
    }

    @GetMapping("/againApply")
    @Operation(summary =  "重新发起申请签约链", description = "重新发起申请签约链")
    @Parameter(name = "blockchainShopId", description = "商铺签约链id")
    public ServerResponseEntity<Void> againApply(@RequestParam(name="blockchainShopId") Long blockchainShopId) {
        blockchainShopService.update(Wrappers.lambdaUpdate(BlockchainShop.class).eq(BlockchainShop::getBlockchainShopId, blockchainShopId)
                .set(BlockchainShop::getStatus, 0).set(BlockchainShop::getApplyTime, new Date()));
        return ServerResponseEntity.success();
    }
}
